﻿using System.Linq;
using System.Xml.Linq;
using System.Collections.Generic;
using System;

namespace XMLProviders.Extensions
{
    public static class XMLExtensions
    {
        /// <summary>
        /// Return the value from a child element of the supplied element as a string , but only of the child element exists
        /// </summary>
        /// <param name="element">The element that contains the child element we want</param>
        /// <param name="valueName">The name of the value to return</param>
        /// <returns>A string containing either the child elements data, or a blank string</returns>
        public static string GetChildElementStringValue(this XElement element, string valueName)
        {
            string result = string.Empty;

            if (element != null)
            {
                // Search for the child element and return its value if it exists
                XElement childElement = element.Elements().Where(x => x.Name == valueName).FirstOrDefault();
                if (childElement != null)
                {
                    result = childElement.Value;
                }
            }

            return result;
        }

        /// <summary>
        /// Return the value from a child element of the supplied element as a Guid , but only of the child element exists
        /// </summary>
        /// <param name="element">The element that contains the child element we want</param>
        /// <param name="valueName">The name of the value to return</param>
        /// <returns>A Guid containing either the child elements data or and empty Guid</returns>
        public static Guid GetChildElementGuidValue(this XElement element, string valueName)
        {
            Guid result = Guid.Empty;

            if (element != null)
            {
                // Search for the child element and return its value if it exists
                XElement childElement = element.Elements().Where(x => x.Name == valueName).FirstOrDefault();
                if (childElement != null)
                {
                    if (!Guid.TryParse(childElement.Value, out result))
                    {
                        result = Guid.Empty;
                    }
                
                }
            }

            return result;
        }

        /// <summary>
        /// Return the value from a child element of the supplied element as a boolean , but only of the child element exists
        /// </summary>
        /// <param name="element">The element that contains the child element we want</param>
        /// <param name="valueName">The name of the value to return</param>
        /// <param name="defaultValue">The default value to use if the element cannot be found</param>
        /// <returns>A boolean containing the value os the child element</returns>
        public static bool GetChildElementBoolValue(this XElement element, string valueName, bool defaultValue)
        {
            bool result = defaultValue;

            if (element != null)
            {
                // Search for the child element
                XElement childElement = element.Elements().Where(x => x.Name == valueName).FirstOrDefault();

                // If the child element exists then convert it from a string to a boolean and return the result
                if (childElement != null)
                {
                    switch (childElement.Value.ToLower())
                    {
                        case "true":
                        case "t":
                        case "1":
                        {
                            result = true;
                            break;
                        }
                        default:
                        {
                            result = false;
                            break;
                        }

                    }
                }
            }

            return result;
        }

        /// <summary>
        /// Search the supplied element for the specified child element and then return the child elements children as
        /// a dictionary of strings. The element name will be the key and the element value will be the value)
        /// </summary>
        /// <param name="element">The element that contains the child element we want</param>
        /// <param name="valueName">The name of the child element whose children we want as a dictionary</param>
        /// <returns>A dictionary of data representing the child elements respective children</returns>
        public static Dictionary<string, string> GetChildElementDictionary(this XElement element, string valueName)
        {
            Dictionary<string, string> result = new Dictionary<string, string>();

            if (element != null)
            {
                // Get the child element whose children we will turn into a dictionary
                XElement childElement = element.Elements().Where(x => x.Name == valueName).FirstOrDefault();

                if ((childElement != null) && (childElement.HasElements))
                {
                    foreach (XElement item in element.Elements())
                    {
                        result.Add(item.Name.LocalName, item.Value);
                    }
                }
            }

            return result;
        }
    }
}
